1 Method

Transcript-level quantification was performed with lr-kallisto (v0.51.1), kallisto_optoff_k64 binary, using the GENCODE v48 human genome, transcriptome, and annotated GTF as references. Isoform abundance estimates (TxPM) and counts were imported into R where Differential Isoform Usage and splicing analyses were performed with IsoformSwitchAnalyzeR (v2.4.0).

The design matrix incorporated disease status (AD vs. CTRL) as the primary factor while adjusting for sex as a covariate. Filtering was performed with default parameters (alpha < 0.05 and absolute isoform fraction difference (dIF) > 0.1) to retain genes with expression ≥1 TPM and isoforms with non-zero expression.

Differential Isoform Usage was also assessed with significance thresholds of alpha < 0.05 and absolute dIF > 0.1. 26 total significant isoform switches were further characterized by integrating gene-level and isoform-level differential expression results from DESeq2 (v1.44.0). Functional consequences were predicted through four external computational tools: SignalP 6.0 for signal peptides, DeepTMHMM for protein topology, DeepLoc2.0 for subcellular localization, and Pfam for protein domains. We further evaluated the 26 significant isoform switches (isoform switch q value < 0.05) for switching consequences, localization shifts, and alternative splicing following the IsoformSwitchAnalyzeR vignette with default parameters.

All analyses were conducted in R (v4.4.0) and tidyverse (v2.0.0) ecosystem packages. Plots were generated with IsoformSwitchAnalyzeR or ggplot2 (v3.5.2).


# libraries
library(ggrepel)
## Loading required package: ggplot2
library(IsoformSwitchAnalyzeR)
## Loading required package: limma
## Loading required package: DEXSeq
## Loading required package: BiocParallel
## Loading required package: Biobase
## Loading required package: BiocGenerics
## 
## Attaching package: 'BiocGenerics'
## The following object is masked from 'package:limma':
## 
##     plotMA
## The following objects are masked from 'package:stats':
## 
##     IQR, mad, sd, var, xtabs
## The following objects are masked from 'package:base':
## 
##     anyDuplicated, aperm, append, as.data.frame, basename, cbind,
##     colnames, dirname, do.call, duplicated, eval, evalq, Filter, Find,
##     get, grep, grepl, intersect, is.unsorted, lapply, Map, mapply,
##     match, mget, order, paste, pmax, pmax.int, pmin, pmin.int,
##     Position, rank, rbind, Reduce, rownames, sapply, setdiff, table,
##     tapply, union, unique, unsplit, which.max, which.min
## Welcome to Bioconductor
## 
##     Vignettes contain introductory material; view with
##     'browseVignettes()'. To cite Bioconductor, see
##     'citation("Biobase")', and for packages 'citation("pkgname")'.
## Loading required package: SummarizedExperiment
## Loading required package: MatrixGenerics
## Loading required package: matrixStats
## 
## Attaching package: 'matrixStats'
## The following objects are masked from 'package:Biobase':
## 
##     anyMissing, rowMedians
## 
## Attaching package: 'MatrixGenerics'
## The following objects are masked from 'package:matrixStats':
## 
##     colAlls, colAnyNAs, colAnys, colAvgsPerRowSet, colCollapse,
##     colCounts, colCummaxs, colCummins, colCumprods, colCumsums,
##     colDiffs, colIQRDiffs, colIQRs, colLogSumExps, colMadDiffs,
##     colMads, colMaxs, colMeans2, colMedians, colMins, colOrderStats,
##     colProds, colQuantiles, colRanges, colRanks, colSdDiffs, colSds,
##     colSums2, colTabulates, colVarDiffs, colVars, colWeightedMads,
##     colWeightedMeans, colWeightedMedians, colWeightedSds,
##     colWeightedVars, rowAlls, rowAnyNAs, rowAnys, rowAvgsPerColSet,
##     rowCollapse, rowCounts, rowCummaxs, rowCummins, rowCumprods,
##     rowCumsums, rowDiffs, rowIQRDiffs, rowIQRs, rowLogSumExps,
##     rowMadDiffs, rowMads, rowMaxs, rowMeans2, rowMedians, rowMins,
##     rowOrderStats, rowProds, rowQuantiles, rowRanges, rowRanks,
##     rowSdDiffs, rowSds, rowSums2, rowTabulates, rowVarDiffs, rowVars,
##     rowWeightedMads, rowWeightedMeans, rowWeightedMedians,
##     rowWeightedSds, rowWeightedVars
## The following object is masked from 'package:Biobase':
## 
##     rowMedians
## Loading required package: GenomicRanges
## Loading required package: stats4
## Loading required package: S4Vectors
## 
## Attaching package: 'S4Vectors'
## The following object is masked from 'package:utils':
## 
##     findMatches
## The following objects are masked from 'package:base':
## 
##     expand.grid, I, unname
## Loading required package: IRanges
## Loading required package: GenomeInfoDb
## Loading required package: DESeq2
## Loading required package: AnnotationDbi
## Loading required package: RColorBrewer
## Loading required package: satuRn
## Loading required package: sva
## Loading required package: mgcv
## Loading required package: nlme
## 
## Attaching package: 'nlme'
## The following object is masked from 'package:IRanges':
## 
##     collapse
## This is mgcv 1.9-1. For overview type 'help("mgcv-package")'.
## Loading required package: genefilter
## 
## Attaching package: 'genefilter'
## The following objects are masked from 'package:MatrixGenerics':
## 
##     rowSds, rowVars
## The following objects are masked from 'package:matrixStats':
## 
##     rowSds, rowVars
## Loading required package: pfamAnalyzeR
## Loading required package: readr
## 
## Attaching package: 'readr'
## The following object is masked from 'package:genefilter':
## 
##     spec
## Loading required package: stringr
## Loading required package: dplyr
## 
## Attaching package: 'dplyr'
## The following object is masked from 'package:nlme':
## 
##     collapse
## The following object is masked from 'package:AnnotationDbi':
## 
##     select
## The following objects are masked from 'package:GenomicRanges':
## 
##     intersect, setdiff, union
## The following object is masked from 'package:GenomeInfoDb':
## 
##     intersect
## The following objects are masked from 'package:IRanges':
## 
##     collapse, desc, intersect, setdiff, slice, union
## The following objects are masked from 'package:S4Vectors':
## 
##     first, intersect, rename, setdiff, setequal, union
## The following object is masked from 'package:matrixStats':
## 
##     count
## The following object is masked from 'package:Biobase':
## 
##     combine
## The following objects are masked from 'package:BiocGenerics':
## 
##     combine, intersect, setdiff, union
## The following objects are masked from 'package:stats':
## 
##     filter, lag
## The following objects are masked from 'package:base':
## 
##     intersect, setdiff, setequal, union
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ forcats   1.0.0     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.1.0
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ lubridate::%within%()    masks IRanges::%within%()
## ✖ dplyr::collapse()        masks nlme::collapse(), IRanges::collapse()
## ✖ dplyr::combine()         masks Biobase::combine(), BiocGenerics::combine()
## ✖ dplyr::count()           masks matrixStats::count()
## ✖ dplyr::desc()            masks IRanges::desc()
## ✖ tidyr::expand()          masks S4Vectors::expand()
## ✖ dplyr::filter()          masks stats::filter()
## ✖ dplyr::first()           masks S4Vectors::first()
## ✖ dplyr::lag()             masks stats::lag()
## ✖ BiocGenerics::Position() masks ggplot2::Position(), base::Position()
## ✖ purrr::reduce()          masks GenomicRanges::reduce(), IRanges::reduce()
## ✖ dplyr::rename()          masks S4Vectors::rename()
## ✖ lubridate::second()      masks S4Vectors::second()
## ✖ lubridate::second<-()    masks S4Vectors::second<-()
## ✖ dplyr::select()          masks AnnotationDbi::select()
## ✖ dplyr::slice()           masks IRanges::slice()
## ✖ readr::spec()            masks genefilter::spec()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
knitr::opts_chunk$set(echo=TRUE, warning=FALSE, message=FALSE, fig.width=12, fig.height=8, fig.align = "center")
# print session information
sessionInfo()
## R version 4.4.0 (2024-04-24)
## Platform: x86_64-pc-linux-gnu
## Running under: AlmaLinux 8.10 (Cerulean Leopard)
## 
## Matrix products: default
## BLAS/LAPACK: FlexiBLAS NETLIB;  LAPACK version 3.11.0
## 
## locale:
##  [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C              
##  [3] LC_TIME=en_US.UTF-8        LC_COLLATE=en_US.UTF-8    
##  [5] LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
##  [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                 
##  [9] LC_ADDRESS=C               LC_TELEPHONE=C            
## [11] LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       
## 
## time zone: America/New_York
## tzcode source: system (glibc)
## 
## attached base packages:
## [1] stats4    stats     graphics  grDevices utils     datasets  methods  
## [8] base     
## 
## other attached packages:
##  [1] lubridate_1.9.3             forcats_1.0.0              
##  [3] purrr_1.1.0                 tidyr_1.3.1                
##  [5] tibble_3.2.1                tidyverse_2.0.0            
##  [7] IsoformSwitchAnalyzeR_2.4.0 pfamAnalyzeR_1.4.0         
##  [9] dplyr_1.1.4                 stringr_1.5.1              
## [11] readr_2.1.5                 sva_3.52.0                 
## [13] genefilter_1.86.0           mgcv_1.9-1                 
## [15] nlme_3.1-164                satuRn_1.12.0              
## [17] DEXSeq_1.50.0               RColorBrewer_1.1-3         
## [19] AnnotationDbi_1.66.0        DESeq2_1.44.0              
## [21] SummarizedExperiment_1.34.0 GenomicRanges_1.56.0       
## [23] GenomeInfoDb_1.40.0         IRanges_2.38.0             
## [25] S4Vectors_0.42.1            MatrixGenerics_1.16.0      
## [27] matrixStats_1.5.0           Biobase_2.64.0             
## [29] BiocGenerics_0.50.0         BiocParallel_1.38.0        
## [31] limma_3.60.6                ggrepel_0.9.6              
## [33] ggplot2_3.5.2              
## 
## loaded via a namespace (and not attached):
##   [1] rstudioapi_0.16.0        jsonlite_2.0.0           tximport_1.32.0         
##   [4] magrittr_2.0.3           GenomicFeatures_1.56.0   farver_2.1.2            
##   [7] rmarkdown_2.29           BiocIO_1.14.0            zlibbioc_1.50.0         
##  [10] vctrs_0.6.5              locfdr_1.1-8             memoise_2.0.1           
##  [13] Rsamtools_2.20.0         RCurl_1.98-1.14          htmltools_0.5.8.1       
##  [16] S4Arrays_1.4.0           progress_1.2.3           AnnotationHub_3.12.0    
##  [19] lambda.r_1.2.4           curl_6.4.0               SparseArray_1.4.0       
##  [22] sass_0.4.10              bslib_0.9.0              plyr_1.8.9              
##  [25] httr2_1.0.1              futile.options_1.0.1     cachem_1.1.0            
##  [28] GenomicAlignments_1.40.0 lifecycle_1.0.4          pkgconfig_2.0.3         
##  [31] Matrix_1.7-0             R6_2.6.1                 fastmap_1.2.0           
##  [34] GenomeInfoDbData_1.2.12  digest_0.6.37            colorspace_2.1-1        
##  [37] tximeta_1.22.1           geneplotter_1.82.0       RSQLite_2.3.6           
##  [40] hwriter_1.3.2.1          filelock_1.0.3           timechange_0.3.0        
##  [43] httr_1.4.7               abind_1.4-8              compiler_4.4.0          
##  [46] bit64_4.0.5              withr_3.0.2              DBI_1.2.2               
##  [49] biomaRt_2.60.1           rappdirs_0.3.3           DelayedArray_0.30.1     
##  [52] rjson_0.2.21             tools_4.4.0              glue_1.8.0              
##  [55] VennDiagram_1.7.3        restfulr_0.0.15          grid_4.4.0              
##  [58] reshape2_1.4.4           generics_0.1.4           gtable_0.3.6            
##  [61] BSgenome_1.72.0          tzdb_0.4.0               ensembldb_2.28.0        
##  [64] hms_1.1.3                xml2_1.3.6               XVector_0.44.0          
##  [67] BiocVersion_3.19.1       pillar_1.11.0            splines_4.4.0           
##  [70] BiocFileCache_2.12.0     lattice_0.22-6           survival_3.6-4          
##  [73] rtracklayer_1.64.0       bit_4.0.5                annotate_1.82.0         
##  [76] tidyselect_1.2.1         locfit_1.5-9.9           Biostrings_2.72.0       
##  [79] pbapply_1.7-2            knitr_1.50               gridExtra_2.3           
##  [82] ProtGenerics_1.36.0      edgeR_4.2.0              futile.logger_1.4.3     
##  [85] xfun_0.52                statmod_1.5.0            stringi_1.8.3           
##  [88] UCSC.utils_1.0.0         lazyeval_0.2.2           yaml_2.3.10             
##  [91] boot_1.3-30              evaluate_1.0.4           codetools_0.2-20        
##  [94] BiocManager_1.30.26      cli_3.6.5                xtable_1.8-4            
##  [97] jquerylib_0.1.4          dichromat_2.0-0.1        Rcpp_1.1.0              
## [100] dbplyr_2.5.0             png_0.1-8                XML_3.99-0.16.1         
## [103] parallel_4.4.0           blob_1.2.4               prettyunits_1.2.0       
## [106] AnnotationFilter_1.28.0  bitops_1.0-9             pwalign_1.0.0           
## [109] txdbmaker_1.0.1          scales_1.4.0             crayon_1.5.3            
## [112] rlang_1.1.6              formatR_1.14             KEGGREST_1.44.0

2 Import Kallisto Count Data

# import counts
kallisto_counts_path <- "../kallisto_counts/"

kallisto_quant <- importIsoformExpression(
    parentDir = kallisto_counts_path,
    addIsofomIdAsColumn = TRUE
)

new_col_names <- c("isoform_id","bc01_CTRL", "bc02_CTRL", "bc03_CTRL", "bc04_CTRL", "bc09_AD", "bc10_AD", "bc11_AD", "bc12_AD")

names(kallisto_quant$abundance) <- new_col_names
names(kallisto_quant$counts) <- new_col_names
names(kallisto_quant$length) <- new_col_names

kallisto_quant$counts
# write.csv(kallisto_quant$counts, "kallisto_counts_all.csv", row.names = FALSE)

3 Generate Design Matrix with Sex as Covariate

# generate design matrix

sampleID <- colnames(kallisto_quant$abundance[-1])
condition <- gsub('.*_', '', colnames(kallisto_quant$abundance[-1])) %>% as.factor()
design <- data.frame(
    sampleID = sampleID,
    condition = condition
)

# add sex and ageand race as covariates
design$sex <- factor(c('male','male','male','female','female','female','male','female'))
#design$race <- factor(c('Black','Black', 'White', 'White', 'White','White','Black','Black'))

design

4 Create Switch Analyzer Object

Used GENCODE v48 .gtf file and transcripts .fa file

# create switchAnalyzeRlist object

gtf_file <- "../../refs/gencode.v48.annotation.gtf"
transcriptome_fasta <- "../../refs/gencode.v48.transcripts.fa.gz"

switch_analyzer_list <- importRdata(
    isoformCountMatrix   = kallisto_quant$counts,
    isoformRepExpression   = kallisto_quant$abundance,
    designMatrix         = design,
    isoformExonAnnoation = gtf_file,
    isoformNtFasta       = transcriptome_fasta,
    fixStringTieAnnotationProblem = TRUE,
    showProgress = TRUE
)
##   |                                                                              |                                                                      |   0%  |                                                                              |===================================                                   |  50%  |                                                                              |======================================================================| 100%
##   |                                                                              |                                                                      |   0%  |                                                                              |======================================================================| 100%
##   comparison estimated_genes_with_dtu
## 1 AD vs CTRL                    0 - 0
summary(switch_analyzer_list)
## This switchAnalyzeRlist list contains:
##  152394 isoforms from 39993 genes
##  1 comparison from 2 conditions (in total 8 samples)
## 
## Feature analyzed:
## [1] "ORFs, ntSequence"

5 Filtering

FDR < 0.05

dIFcutoff = 0.1

geneExpressionCutoff =1 FPKM/TPM/RPKM

isoformExpressionCutoff = 0 RPKM/FPKM (removes completely unused isoforms)

# filter:
# Multi-isoform genes
# Gene expression
# Isoform expression
# Isoform Fraction (isoform usage)
# Unwanted isoform classes
# Unwanted gene biotypes
# Genes without differential isoform usage

# default cutoffs:
# alpha=0.05 --> FDR
# dIFcutoff = 0.1 --> changes in absolute isoform usage / analogous to log2FC cut-off
# geneExpressionCutoff --> Default is 1 FPKM/TPM/RPKM
# isoformExpressionCutoff --> Default is 0 (which removes completely unused isoforms); also in RPKM/FPKM

switch_analyzer_list_filtered <- preFilter(
    switchAnalyzeRlist = switch_analyzer_list,
    geneExpressionCutoff = 1,
    isoformExpressionCutoff = 0,
    removeSingleIsoformGenes = TRUE
)

6 Switch Analysis with DEXSeq

FDR < 0.05

dIFcutoff = 0.1

reduceToSwitchingGenes = TRUE (only uses genes w at least 1 significant differentially used isoform)

# switch analysis with DEXseq
# default cutoffs:
# alpha=0.05 --> FDR
# dIFcutoff = 0.1 --> changes in absolute isoform usage / analogous to log2FC cut-off
# reduceToSwitchingGenes --> only uses genes w at least 1 sig differentially used isoform

switch_analyzer_list_filtered <- isoformSwitchTestDEXSeq(
    switchAnalyzeRlist = switch_analyzer_list_filtered,
    reduceToSwitchingGenes=TRUE
)
extractSwitchSummary(switch_analyzer_list_filtered)
# extract switch amino acid and nt sequences to files
switch_analyzer_list_filtered <- extractSequence(
    switch_analyzer_list_filtered, 
    pathToOutput = "results_kallisto_isoformanalyzer",
    writeToFile=TRUE
)

6.1 Significant Isoform Switches

Arranged by isoform_switch_q_value

PTC = pre-mature termination codon

# PTC means --> pre-mature termination codons

switch_analyzer_list_df <- switch_analyzer_list_filtered$isoformFeatures %>% 
  as.data.frame() %>% 
  arrange(isoform_switch_q_value)

switch_analyzer_list_df
#write.csv(switch_analyzer_list_df, "kallisto_isoform_switch_analysis.csv", row.names = FALSE)

6.2 Add Differential Gene and Isoform Expression

Add padj values

# add differential gene and isoform expression to switchanalyzer object

diff_gene_expr <- read.csv("../differential_expression/kallisto_DGE.csv")
diff_iso_expr <- read.csv("../differential_expression/kallisto_differential_isoform_expression.csv")

switch_analyzer_list_df <- switch_analyzer_list_df %>%
  left_join(
    diff_gene_expr %>% dplyr::select(gene_name, padj), 
    by = join_by(gene_id == gene_name)) %>%
  mutate(gene_q_value = padj) %>%
  subset(select = -padj) %>%
  left_join(
    diff_iso_expr %>% dplyr::select(isoform_id, padj), 
    by = "isoform_id") %>%
  mutate(iso_q_value = padj) %>%
  subset(select = -padj)

switch_analyzer_list_filtered$isoformFeatures$gene_q_value <- switch_analyzer_list_df$gene_q_value
switch_analyzer_list_filtered$isoformFeatures$iso_q_value <- switch_analyzer_list_df$iso_q_value

# save switch_analyzer_list_filtered as .RDS file for future use
#saveRDS(switch_analyzer_list_filtered, file = "switch_analyzer_list_filtered_sex.rds")
# significant isoform switches (iso_switch_q_value < 0.05)
switch_analyzer_list_filtered <- readRDS("./switch_analyzer_list_filtered_sex.rds")
switch_analyzer_list_df <- switch_analyzer_list_filtered$isoformFeatures %>% as.data.frame()

significant_iso_switches <- switch_analyzer_list_df %>%
  dplyr::filter(isoform_switch_q_value < 0.05) %>%
  arrange(isoform_switch_q_value) %>%
  dplyr::select(isoform_id, gene_id, condition_1, condition_2,iso_biotype, IF1, IF2, dIF, isoform_switch_q_value, gene_switch_q_value, PTC)

7 Volcano-like Plot of Significant Isoform Switches

reference is AD

isoform_switch_q_value < 0.05

dIF < -0.1 or > 0.1

# volcano-like plot of isoform switches AD vs CTRL
ggplot(data = switch_analyzer_list_df, aes(x = dIF, y = -log10(isoform_switch_q_value))) +
  geom_point(
    aes(color = abs(dIF) > 0.1 & isoform_switch_q_value < 0.05),
    size = 1
  ) +
  geom_hline(yintercept = -log10(0.05), linetype = 'dashed') +
  geom_vline(xintercept = c(-0.1, 0.1), linetype = 'dashed') +
  scale_color_manual('Significant\nIsoform Switch',
                     values = c('FALSE' = 'blue', 'TRUE' = 'orange')) +
  labs(x = 'dIF', y = '-Log10 (Isoform Switch Q Value)') +
  ggtitle("Significant Isoform Switches AD vs. CTRL (Q value < 0.05)") +
  ggrepel::geom_text_repel(
    aes(label = ifelse(abs(dIF) > 0.1 & isoform_switch_q_value < 0.05,
                       paste0(gene_id, " (", isoform_id, ")"),
                       '')),
    size = 2.5
  ) +
  theme_bw()

8 External Analyses

signal peptides, protein topology, subcellular locations, and protein domains

# SignalP - Prediction of Signal Peptides
# https://services.healthtech.dtu.dk/services/SignalP-6.0/
switch_analyzer_list_filtered <- analyzeSignalP(
    switchAnalyzeRlist       = switch_analyzer_list_filtered,
    pathToSignalPresultFile  = "./biolib_results/signalp/prediction_results.txt"
)

# analyzeDeepTMHMM : Prediction of protein topology — the proteins location compared to the cell membrane. Can be intracellular, transmembrane (TM) or extracellular.
# https://dtu.biolib.com/results/0797323f-c818-4343-88d7-43009062fc59/?token=ka2OLAD9XhWPRFIO
switch_analyzer_list_filtered <- analyzeDeepTMHMM(
    switchAnalyzeRlist   = switch_analyzer_list_filtered,
    pathToDeepTMHMMresultFile = "./biolib_results/deeptmhmm/TMRs.gff3",
    showProgress=TRUE
)
##   |                                                                              |                                                                      |   0%  |                                                                              |=                                                                     |   1%  |                                                                              |==                                                                    |   2%  |                                                                              |==                                                                    |   3%  |                                                                              |===                                                                   |   4%  |                                                                              |====                                                                  |   5%  |                                                                              |=====                                                                 |   6%  |                                                                              |=====                                                                 |   8%  |                                                                              |======                                                                |   9%  |                                                                              |=======                                                               |  10%  |                                                                              |========                                                              |  11%  |                                                                              |========                                                              |  12%  |                                                                              |=========                                                             |  13%  |                                                                              |==========                                                            |  14%  |                                                                              |===========                                                           |  15%  |                                                                              |===========                                                           |  16%  |                                                                              |============                                                          |  17%  |                                                                              |=============                                                         |  18%  |                                                                              |==============                                                        |  19%  |                                                                              |==============                                                        |  20%  |                                                                              |===============                                                       |  22%  |                                                                              |================                                                      |  23%  |                                                                              |=================                                                     |  24%  |                                                                              |=================                                                     |  25%  |                                                                              |==================                                                    |  26%  |                                                                              |===================                                                   |  27%  |                                                                              |====================                                                  |  28%  |                                                                              |====================                                                  |  29%  |                                                                              |=====================                                                 |  30%  |                                                                              |======================                                                |  31%  |                                                                              |=======================                                               |  32%  |                                                                              |=======================                                               |  33%  |                                                                              |========================                                              |  34%  |                                                                              |=========================                                             |  35%  |                                                                              |==========================                                            |  37%  |                                                                              |==========================                                            |  38%  |                                                                              |===========================                                           |  39%  |                                                                              |============================                                          |  40%  |                                                                              |=============================                                         |  41%  |                                                                              |=============================                                         |  42%  |                                                                              |==============================                                        |  43%  |                                                                              |===============================                                       |  44%  |                                                                              |================================                                      |  45%  |                                                                              |================================                                      |  46%  |                                                                              |=================================                                     |  47%  |                                                                              |==================================                                    |  48%  |                                                                              |===================================                                   |  49%  |                                                                              |===================================                                   |  51%  |                                                                              |====================================                                  |  52%  |                                                                              |=====================================                                 |  53%  |                                                                              |======================================                                |  54%  |                                                                              |======================================                                |  55%  |                                                                              |=======================================                               |  56%  |                                                                              |========================================                              |  57%  |                                                                              |=========================================                             |  58%  |                                                                              |=========================================                             |  59%  |                                                                              |==========================================                            |  60%  |                                                                              |===========================================                           |  61%  |                                                                              |============================================                          |  62%  |                                                                              |============================================                          |  63%  |                                                                              |=============================================                         |  65%  |                                                                              |==============================================                        |  66%  |                                                                              |===============================================                       |  67%  |                                                                              |===============================================                       |  68%  |                                                                              |================================================                      |  69%  |                                                                              |=================================================                     |  70%  |                                                                              |==================================================                    |  71%  |                                                                              |==================================================                    |  72%  |                                                                              |===================================================                   |  73%  |                                                                              |====================================================                  |  74%  |                                                                              |=====================================================                 |  75%  |                                                                              |=====================================================                 |  76%  |                                                                              |======================================================                |  77%  |                                                                              |=======================================================               |  78%  |                                                                              |========================================================              |  80%  |                                                                              |========================================================              |  81%  |                                                                              |=========================================================             |  82%  |                                                                              |==========================================================            |  83%  |                                                                              |===========================================================           |  84%  |                                                                              |===========================================================           |  85%  |                                                                              |============================================================          |  86%  |                                                                              |=============================================================         |  87%  |                                                                              |==============================================================        |  88%  |                                                                              |==============================================================        |  89%  |                                                                              |===============================================================       |  90%  |                                                                              |================================================================      |  91%  |                                                                              |=================================================================     |  92%  |                                                                              |=================================================================     |  94%  |                                                                              |==================================================================    |  95%  |                                                                              |===================================================================   |  96%  |                                                                              |====================================================================  |  97%  |                                                                              |====================================================================  |  98%  |                                                                              |===================================================================== |  99%  |                                                                              |======================================================================| 100%
# analyzeDeepLoc2 - prediction of sub-cellular localization(s) of protein
# deeploc2.0
# https://services.healthtech.dtu.dk/services/DeepLoc-2.0/
switch_analyzer_list_filtered <- analyzeDeepLoc2(
    switchAnalyzeRlist = switch_analyzer_list_filtered,
    pathToDeepLoc2resultFile = "./biolib_results/deeploc2/results_6894F7A60000BCEA626E8931.csv",
    quiet = FALSE
)

# pfam
# see /bin/isoform_switch_analyzer/biolib_results/pfam_hmmscan/ directory for shell script
switch_analyzer_list_filtered <- analyzePFAM(
    switchAnalyzeRlist   = switch_analyzer_list_filtered,
    pathToPFAMresultFile = "./biolib_results/pfam_hmmscan/Pfam_result.txt",
    showProgress=TRUE
)
##   |                                                                              |                                                                      |   0%  |                                                                              |=                                                                     |   2%  |                                                                              |===                                                                   |   4%  |                                                                              |====                                                                  |   6%  |                                                                              |=====                                                                 |   7%  |                                                                              |======                                                                |   9%  |                                                                              |========                                                              |  11%  |                                                                              |=========                                                             |  13%  |                                                                              |==========                                                            |  15%  |                                                                              |============                                                          |  17%  |                                                                              |=============                                                         |  19%  |                                                                              |==============                                                        |  20%  |                                                                              |================                                                      |  22%  |                                                                              |=================                                                     |  24%  |                                                                              |==================                                                    |  26%  |                                                                              |===================                                                   |  28%  |                                                                              |=====================                                                 |  30%  |                                                                              |======================                                                |  31%  |                                                                              |=======================                                               |  33%  |                                                                              |=========================                                             |  35%  |                                                                              |==========================                                            |  37%  |                                                                              |===========================                                           |  39%  |                                                                              |=============================                                         |  41%  |                                                                              |==============================                                        |  43%  |                                                                              |===============================                                       |  44%  |                                                                              |================================                                      |  46%  |                                                                              |==================================                                    |  48%  |                                                                              |===================================                                   |  50%  |                                                                              |====================================                                  |  52%  |                                                                              |======================================                                |  54%  |                                                                              |=======================================                               |  56%  |                                                                              |========================================                              |  57%  |                                                                              |=========================================                             |  59%  |                                                                              |===========================================                           |  61%  |                                                                              |============================================                          |  63%  |                                                                              |=============================================                         |  65%  |                                                                              |===============================================                       |  67%  |                                                                              |================================================                      |  69%  |                                                                              |=================================================                     |  70%  |                                                                              |===================================================                   |  72%  |                                                                              |====================================================                  |  74%  |                                                                              |=====================================================                 |  76%  |                                                                              |======================================================                |  78%  |                                                                              |========================================================              |  80%  |                                                                              |=========================================================             |  81%  |                                                                              |==========================================================            |  83%  |                                                                              |============================================================          |  85%  |                                                                              |=============================================================         |  87%  |                                                                              |==============================================================        |  89%  |                                                                              |================================================================      |  91%  |                                                                              |=================================================================     |  93%  |                                                                              |==================================================================    |  94%  |                                                                              |===================================================================   |  96%  |                                                                              |===================================================================== |  98%  |                                                                              |======================================================================| 100%

8.1 Signal Peptide Analysis

switch_analyzer_list_filtered$signalPeptideAnalysis %>% dplyr::left_join(switch_analyzer_list_filtered$isoformFeatures %>% dplyr::select(isoform_id, gene_name), by = join_by(isoform_id)) %>% dplyr::select(isoform_id, gene_name, everything())

8.2 Topology Analysis

switch_analyzer_list_filtered$topologyAnalysis %>% dplyr::left_join(switch_analyzer_list_filtered$isoformFeatures %>% dplyr::select(isoform_id, gene_name), by = join_by(isoform_id)) %>% dplyr::select(isoform_id, gene_name, everything())

8.3 Subcellular Location Analysis

switch_analyzer_list_filtered$subCellLocationAnalysis %>% dplyr::left_join(switch_analyzer_list_filtered$isoformFeatures %>% dplyr::select(isoform_id, gene_name), by = join_by(isoform_id)) %>% dplyr::select(isoform_id, gene_name, everything())

8.4 Protein Domain Analysis

Sorted by E_value (significance)

switch_analyzer_list_filtered$domainAnalysis %>% dplyr::left_join(switch_analyzer_list_filtered$isoformFeatures %>% dplyr::select(isoform_id, gene_name), by = join_by(isoform_id)) %>% dplyr::select(isoform_id, gene_name, everything()) %>% arrange(E_value)

9 Isoform Switch Plots with External Analyses

# isoform switch visualization

top_switches <- extractTopSwitches( 
    switch_analyzer_list_filtered, 
    filterForConsequences = FALSE, 
    n = NA,                  # n=NA: all features are returned
    extractGenes = FALSE,    # when FALSE isoforms are returned
    sortByQvals = TRUE,
)

plot_isoform_switch <- function(isoform_switch_list, gene) { switchPlot( isoform_switch_list, gene=gene, condition1 = 'AD', condition2 = 'CTRL', plotTopology = TRUE ) }

for (gene in top_switches$gene_id) { plot_isoform_switch(switch_analyzer_list_filtered, gene) }

10 Alternative Splicing Analysis

Reference is AD

# alternative splicing analysis
switch_analyzer_list_filtered <- analyzeAlternativeSplicing(
    switchAnalyzeRlist = switch_analyzer_list_filtered,
    quiet=TRUE
)
switch_analyzer_list_filtered$AlternativeSplicingAnalysis
extractSplicingSummary( switch_analyzer_list_filtered )

extractSplicingEnrichment( switch_analyzer_list_filtered )
extractSplicingGenomeWide( switch_analyzer_list_filtered )

11 Isoform Switch Consequence Analysis

# switch consequences

consequencesOfInterest <- c(
        'intron_retention',
        'intron_structure',
        'ORF_genomic',
        'ORF_length',
        'NMD_status',
        'signal_peptide_identified',
        'last_exon',
        'exon_number',
        'tss',
        'tts',
        'isoform_seq_similarity',
        'isoform_length',
        "sub_cell_location",
        "sub_cell_shift_to_cell_membrane",
        "sub_cell_shift_to_cytoplasm",
        "sub_cell_shift_to_nucleus",
        "sub_cell_shift_to_Extracellular",
        "isoform_topology",
        "extracellular_region_count",
        "intracellular_region_count",
        "extracellular_region_length",
        "intracellular_region_length",
        '5_utr_seq_similarity',
        '5_utr_length',
        '3_utr_seq_similarity',
        '3_utr_length',
        'domains_identified',
        'domain_isotype',
        'domain_length',
        'genomic_domain_position'
    )

switch_analyzer_list_filtered <- analyzeSwitchConsequences(
    switch_analyzer_list_filtered,
    consequencesToAnalyze = consequencesOfInterest, 
    dIFcutoff = 0.1,
    showProgress=TRUE
)
##   |                                                                              |                                                                      |   0%  |                                                                              |===                                                                   |   4%  |                                                                              |=====                                                                 |   8%  |                                                                              |========                                                              |  12%  |                                                                              |===========                                                           |  15%  |                                                                              |=============                                                         |  19%  |                                                                              |================                                                      |  23%  |                                                                              |===================                                                   |  27%  |                                                                              |======================                                                |  31%  |                                                                              |========================                                              |  35%  |                                                                              |===========================                                           |  38%  |                                                                              |==============================                                        |  42%  |                                                                              |================================                                      |  46%  |                                                                              |===================================                                   |  50%  |                                                                              |======================================                                |  54%  |                                                                              |========================================                              |  58%  |                                                                              |===========================================                           |  62%  |                                                                              |==============================================                        |  65%  |                                                                              |================================================                      |  69%  |                                                                              |===================================================                   |  73%  |                                                                              |======================================================                |  77%  |                                                                              |=========================================================             |  81%  |                                                                              |===========================================================           |  85%  |                                                                              |==============================================================        |  88%  |                                                                              |=================================================================     |  92%  |                                                                              |===================================================================   |  96%  |                                                                              |======================================================================| 100%

11.1 Top 10 Switches by Isoform Switch Q Value

### Extract top switching genes (by q-value)
top_switches_q_value <- extractTopSwitches(
    switch_analyzer_list_filtered, 
    filterForConsequences = TRUE, 
    sortByQvals = TRUE
)

top_switches_q_value

11.2 Top 10 Switches by dIF Value

### Extract top switching genes (by dIF values)
top_switches_dif_value <- extractTopSwitches(
    switch_analyzer_list_filtered, 
    filterForConsequences = TRUE, 
    sortByQvals = FALSE
)
top_switches_dif_value

11.3 Switch Consequence Plot AD vs CTRL

Reference is AD

extractConsequenceEnrichment(
    switch_analyzer_list_filtered,
    consequencesToAnalyze="all",
    analysisOppositeConsequence = TRUE,
    localTheme = theme_bw(base_size = 14),
    returnResult = FALSE # if TRUE returns a data.frame with the summary statistics
)

11.4 Plot of Subcellular Location Shifts

extractSubCellShifts(
    switch_analyzer_list_filtered,
    plotGenes = FALSE,
    locationMinGenes = 1,
    returnResult = FALSE,
    localTheme = theme_bw()
)

LS0tCnRpdGxlOiAicGFjYmlvX2FkX3BpbG90X2lzb2Zvcm1zd2l0Y2hhbmFseXplcl9rYWxsaXN0b19jb3VudHMiCmF1dGhvcjogUmFjaGVsIEJvemFkamlhbgpkYXRlOiA4LzYvMjUKb3V0cHV0OiAKICBodG1sX2RvY3VtZW50OgogICAgY29kZV9mb2xkaW5nOiBzaG93CiAgICBjb2RlX2Rvd25sb2FkOiB0cnVlCiAgICBkZl9wcmludDogcGFnZWQKICAgIHRoZW1lOiB5ZXRpCiAgICBoaWdobGlnaHQ6IHRhbmdvCiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OgogICAgICBjb2xsYXBzZWQ6IGZhbHNlCiAgICAgIHNtb290aF9zY3JvbGw6IGZhbHNlCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKLS0tCgojIE1ldGhvZAoKVHJhbnNjcmlwdC1sZXZlbCBxdWFudGlmaWNhdGlvbiB3YXMgcGVyZm9ybWVkIHdpdGggbHIta2FsbGlzdG8gKHYwLjUxLjEpLCBrYWxsaXN0b19vcHRvZmZfazY0IGJpbmFyeSwgdXNpbmcgdGhlIEdFTkNPREUgdjQ4IGh1bWFuIGdlbm9tZSwgdHJhbnNjcmlwdG9tZSwgYW5kIGFubm90YXRlZCBHVEYgYXMgcmVmZXJlbmNlcy4gSXNvZm9ybSBhYnVuZGFuY2UgZXN0aW1hdGVzIChUeFBNKSBhbmQgY291bnRzIHdlcmUgaW1wb3J0ZWQgaW50byBSIHdoZXJlIERpZmZlcmVudGlhbCBJc29mb3JtIFVzYWdlIGFuZCBzcGxpY2luZyBhbmFseXNlcyB3ZXJlIHBlcmZvcm1lZCB3aXRoIElzb2Zvcm1Td2l0Y2hBbmFseXplUiAodjIuNC4wKS4KClRoZSBkZXNpZ24gbWF0cml4IGluY29ycG9yYXRlZCBkaXNlYXNlIHN0YXR1cyAoQUQgdnMuIENUUkwpIGFzIHRoZSBwcmltYXJ5IGZhY3RvciB3aGlsZSBhZGp1c3RpbmcgZm9yIHNleCBhcyBhIGNvdmFyaWF0ZS4gRmlsdGVyaW5nIHdhcyBwZXJmb3JtZWQgd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMgKGFscGhhIFw8IDAuMDUgYW5kIGFic29sdXRlIGlzb2Zvcm0gZnJhY3Rpb24gZGlmZmVyZW5jZSAoZElGKSBcPiAwLjEpIHRvIHJldGFpbiBnZW5lcyB3aXRoIGV4cHJlc3Npb24g4omlMSBUUE0gYW5kIGlzb2Zvcm1zIHdpdGggbm9uLXplcm8gZXhwcmVzc2lvbi4KCkRpZmZlcmVudGlhbCBJc29mb3JtIFVzYWdlIHdhcyBhbHNvIGFzc2Vzc2VkIHdpdGggc2lnbmlmaWNhbmNlIHRocmVzaG9sZHMgb2YgYWxwaGEgXDwgMC4wNSBhbmQgYWJzb2x1dGUgZElGIFw+IDAuMS4gMjYgdG90YWwgc2lnbmlmaWNhbnQgaXNvZm9ybSBzd2l0Y2hlcyB3ZXJlIGZ1cnRoZXIgY2hhcmFjdGVyaXplZCBieSBpbnRlZ3JhdGluZyBnZW5lLWxldmVsIGFuZCBpc29mb3JtLWxldmVsIGRpZmZlcmVudGlhbCBleHByZXNzaW9uIHJlc3VsdHMgZnJvbSBERVNlcTIgKHYxLjQ0LjApLiBGdW5jdGlvbmFsIGNvbnNlcXVlbmNlcyB3ZXJlIHByZWRpY3RlZCB0aHJvdWdoIGZvdXIgZXh0ZXJuYWwgY29tcHV0YXRpb25hbCB0b29sczogU2lnbmFsUCA2LjAgZm9yIHNpZ25hbCBwZXB0aWRlcywgRGVlcFRNSE1NIGZvciBwcm90ZWluIHRvcG9sb2d5LCBEZWVwTG9jMi4wIGZvciBzdWJjZWxsdWxhciBsb2NhbGl6YXRpb24sIGFuZCBQZmFtIGZvciBwcm90ZWluIGRvbWFpbnMuIFdlIGZ1cnRoZXIgZXZhbHVhdGVkIHRoZSAyNiBzaWduaWZpY2FudCBpc29mb3JtIHN3aXRjaGVzIChpc29mb3JtIHN3aXRjaCBxIHZhbHVlIFw8IDAuMDUpIGZvciBzd2l0Y2hpbmcgY29uc2VxdWVuY2VzLCBsb2NhbGl6YXRpb24gc2hpZnRzLCBhbmQgYWx0ZXJuYXRpdmUgc3BsaWNpbmcgZm9sbG93aW5nIHRoZSBJc29mb3JtU3dpdGNoQW5hbHl6ZVIgdmlnbmV0dGUgd2l0aCBkZWZhdWx0IHBhcmFtZXRlcnMuCgpBbGwgYW5hbHlzZXMgd2VyZSBjb25kdWN0ZWQgaW4gUiAodjQuNC4wKSBhbmQgdGlkeXZlcnNlICh2Mi4wLjApIGVjb3N5c3RlbSBwYWNrYWdlcy4gUGxvdHMgd2VyZSBnZW5lcmF0ZWQgd2l0aCBJc29mb3JtU3dpdGNoQW5hbHl6ZVIgb3IgZ2dwbG90MiAodjMuNS4yKS4KCi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLQoKYGBge3Igc2V0dXB9CiMgbGlicmFyaWVzCmxpYnJhcnkoZ2dyZXBlbCkKbGlicmFyeShJc29mb3JtU3dpdGNoQW5hbHl6ZVIpCmxpYnJhcnkodGlkeXZlcnNlKQoKa25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG89VFJVRSwgd2FybmluZz1GQUxTRSwgbWVzc2FnZT1GQUxTRSwgZmlnLndpZHRoPTEyLCBmaWcuaGVpZ2h0PTgsIGZpZy5hbGlnbiA9ICJjZW50ZXIiKQpgYGAKCmBgYHtyfQojIHByaW50IHNlc3Npb24gaW5mb3JtYXRpb24Kc2Vzc2lvbkluZm8oKQpgYGAKCiMgSW1wb3J0IEthbGxpc3RvIENvdW50IERhdGEKCmBgYHtyfQojIGltcG9ydCBjb3VudHMKa2FsbGlzdG9fY291bnRzX3BhdGggPC0gIi4uL2thbGxpc3RvX2NvdW50cy8iCgprYWxsaXN0b19xdWFudCA8LSBpbXBvcnRJc29mb3JtRXhwcmVzc2lvbigKICAgIHBhcmVudERpciA9IGthbGxpc3RvX2NvdW50c19wYXRoLAogICAgYWRkSXNvZm9tSWRBc0NvbHVtbiA9IFRSVUUKKQoKbmV3X2NvbF9uYW1lcyA8LSBjKCJpc29mb3JtX2lkIiwiYmMwMV9DVFJMIiwgImJjMDJfQ1RSTCIsICJiYzAzX0NUUkwiLCAiYmMwNF9DVFJMIiwgImJjMDlfQUQiLCAiYmMxMF9BRCIsICJiYzExX0FEIiwgImJjMTJfQUQiKQoKbmFtZXMoa2FsbGlzdG9fcXVhbnQkYWJ1bmRhbmNlKSA8LSBuZXdfY29sX25hbWVzCm5hbWVzKGthbGxpc3RvX3F1YW50JGNvdW50cykgPC0gbmV3X2NvbF9uYW1lcwpuYW1lcyhrYWxsaXN0b19xdWFudCRsZW5ndGgpIDwtIG5ld19jb2xfbmFtZXMKCmthbGxpc3RvX3F1YW50JGNvdW50cwoKIyB3cml0ZS5jc3Yoa2FsbGlzdG9fcXVhbnQkY291bnRzLCAia2FsbGlzdG9fY291bnRzX2FsbC5jc3YiLCByb3cubmFtZXMgPSBGQUxTRSkKYGBgCgojIEdlbmVyYXRlIERlc2lnbiBNYXRyaXggd2l0aCBTZXggYXMgQ292YXJpYXRlCgpgYGB7cn0KIyBnZW5lcmF0ZSBkZXNpZ24gbWF0cml4CgpzYW1wbGVJRCA8LSBjb2xuYW1lcyhrYWxsaXN0b19xdWFudCRhYnVuZGFuY2VbLTFdKQpjb25kaXRpb24gPC0gZ3N1YignLipfJywgJycsIGNvbG5hbWVzKGthbGxpc3RvX3F1YW50JGFidW5kYW5jZVstMV0pKSAlPiUgYXMuZmFjdG9yKCkKZGVzaWduIDwtIGRhdGEuZnJhbWUoCiAgICBzYW1wbGVJRCA9IHNhbXBsZUlELAogICAgY29uZGl0aW9uID0gY29uZGl0aW9uCikKCiMgYWRkIHNleCBhbmQgYWdlYW5kIHJhY2UgYXMgY292YXJpYXRlcwpkZXNpZ24kc2V4IDwtIGZhY3RvcihjKCdtYWxlJywnbWFsZScsJ21hbGUnLCdmZW1hbGUnLCdmZW1hbGUnLCdmZW1hbGUnLCdtYWxlJywnZmVtYWxlJykpCiNkZXNpZ24kcmFjZSA8LSBmYWN0b3IoYygnQmxhY2snLCdCbGFjaycsICdXaGl0ZScsICdXaGl0ZScsICdXaGl0ZScsJ1doaXRlJywnQmxhY2snLCdCbGFjaycpKQoKZGVzaWduCmBgYAoKIyBDcmVhdGUgU3dpdGNoIEFuYWx5emVyIE9iamVjdAoKVXNlZCBHRU5DT0RFIHY0OCAuZ3RmIGZpbGUgYW5kIHRyYW5zY3JpcHRzIC5mYSBmaWxlCgpgYGB7cn0KIyBjcmVhdGUgc3dpdGNoQW5hbHl6ZVJsaXN0IG9iamVjdAoKZ3RmX2ZpbGUgPC0gIi4uLy4uL3JlZnMvZ2VuY29kZS52NDguYW5ub3RhdGlvbi5ndGYiCnRyYW5zY3JpcHRvbWVfZmFzdGEgPC0gIi4uLy4uL3JlZnMvZ2VuY29kZS52NDgudHJhbnNjcmlwdHMuZmEuZ3oiCgpzd2l0Y2hfYW5hbHl6ZXJfbGlzdCA8LSBpbXBvcnRSZGF0YSgKICAgIGlzb2Zvcm1Db3VudE1hdHJpeCAgID0ga2FsbGlzdG9fcXVhbnQkY291bnRzLAogICAgaXNvZm9ybVJlcEV4cHJlc3Npb24gICA9IGthbGxpc3RvX3F1YW50JGFidW5kYW5jZSwKICAgIGRlc2lnbk1hdHJpeCAgICAgICAgID0gZGVzaWduLAogICAgaXNvZm9ybUV4b25Bbm5vYXRpb24gPSBndGZfZmlsZSwKICAgIGlzb2Zvcm1OdEZhc3RhICAgICAgID0gdHJhbnNjcmlwdG9tZV9mYXN0YSwKICAgIGZpeFN0cmluZ1RpZUFubm90YXRpb25Qcm9ibGVtID0gVFJVRSwKICAgIHNob3dQcm9ncmVzcyA9IFRSVUUKKQpzdW1tYXJ5KHN3aXRjaF9hbmFseXplcl9saXN0KQpgYGAKCiMgRmlsdGVyaW5nCgpGRFIgXDwgMC4wNQoKZElGY3V0b2ZmID0gMC4xCgpnZW5lRXhwcmVzc2lvbkN1dG9mZiA9MSBGUEtNL1RQTS9SUEtNCgppc29mb3JtRXhwcmVzc2lvbkN1dG9mZiA9IDAgUlBLTS9GUEtNIChyZW1vdmVzIGNvbXBsZXRlbHkgdW51c2VkIGlzb2Zvcm1zKQoKYGBge3J9CiMgZmlsdGVyOgojIE11bHRpLWlzb2Zvcm0gZ2VuZXMKIyBHZW5lIGV4cHJlc3Npb24KIyBJc29mb3JtIGV4cHJlc3Npb24KIyBJc29mb3JtIEZyYWN0aW9uIChpc29mb3JtIHVzYWdlKQojIFVud2FudGVkIGlzb2Zvcm0gY2xhc3NlcwojIFVud2FudGVkIGdlbmUgYmlvdHlwZXMKIyBHZW5lcyB3aXRob3V0IGRpZmZlcmVudGlhbCBpc29mb3JtIHVzYWdlCgojIGRlZmF1bHQgY3V0b2ZmczoKIyBhbHBoYT0wLjA1IC0tPiBGRFIKIyBkSUZjdXRvZmYgPSAwLjEgLS0+IGNoYW5nZXMgaW4gYWJzb2x1dGUgaXNvZm9ybSB1c2FnZSAvIGFuYWxvZ291cyB0byBsb2cyRkMgY3V0LW9mZgojIGdlbmVFeHByZXNzaW9uQ3V0b2ZmIC0tPiBEZWZhdWx0IGlzIDEgRlBLTS9UUE0vUlBLTQojIGlzb2Zvcm1FeHByZXNzaW9uQ3V0b2ZmIC0tPiBEZWZhdWx0IGlzIDAgKHdoaWNoIHJlbW92ZXMgY29tcGxldGVseSB1bnVzZWQgaXNvZm9ybXMpOyBhbHNvIGluIFJQS00vRlBLTQoKc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQgPC0gcHJlRmlsdGVyKAogICAgc3dpdGNoQW5hbHl6ZVJsaXN0ID0gc3dpdGNoX2FuYWx5emVyX2xpc3QsCiAgICBnZW5lRXhwcmVzc2lvbkN1dG9mZiA9IDEsCiAgICBpc29mb3JtRXhwcmVzc2lvbkN1dG9mZiA9IDAsCiAgICByZW1vdmVTaW5nbGVJc29mb3JtR2VuZXMgPSBUUlVFCikKYGBgCgojIFN3aXRjaCBBbmFseXNpcyB3aXRoIERFWFNlcQoKRkRSIFw8IDAuMDUKCmRJRmN1dG9mZiA9IDAuMQoKcmVkdWNlVG9Td2l0Y2hpbmdHZW5lcyA9IFRSVUUgKG9ubHkgdXNlcyBnZW5lcyB3IGF0IGxlYXN0IDEgc2lnbmlmaWNhbnQgZGlmZmVyZW50aWFsbHkgdXNlZCBpc29mb3JtKQoKYGBge3J9CiMgc3dpdGNoIGFuYWx5c2lzIHdpdGggREVYc2VxCiMgZGVmYXVsdCBjdXRvZmZzOgojIGFscGhhPTAuMDUgLS0+IEZEUgojIGRJRmN1dG9mZiA9IDAuMSAtLT4gY2hhbmdlcyBpbiBhYnNvbHV0ZSBpc29mb3JtIHVzYWdlIC8gYW5hbG9nb3VzIHRvIGxvZzJGQyBjdXQtb2ZmCiMgcmVkdWNlVG9Td2l0Y2hpbmdHZW5lcyAtLT4gb25seSB1c2VzIGdlbmVzIHcgYXQgbGVhc3QgMSBzaWcgZGlmZmVyZW50aWFsbHkgdXNlZCBpc29mb3JtCgpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCA8LSBpc29mb3JtU3dpdGNoVGVzdERFWFNlcSgKICAgIHN3aXRjaEFuYWx5emVSbGlzdCA9IHN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkLAogICAgcmVkdWNlVG9Td2l0Y2hpbmdHZW5lcz1UUlVFCikKZXh0cmFjdFN3aXRjaFN1bW1hcnkoc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQpCmBgYAoKYGBge3J9CiMgZXh0cmFjdCBzd2l0Y2ggYW1pbm8gYWNpZCBhbmQgbnQgc2VxdWVuY2VzIHRvIGZpbGVzCnN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkIDwtIGV4dHJhY3RTZXF1ZW5jZSgKICAgIHN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkLCAKICAgIHBhdGhUb091dHB1dCA9ICJyZXN1bHRzX2thbGxpc3RvX2lzb2Zvcm1hbmFseXplciIsCiAgICB3cml0ZVRvRmlsZT1UUlVFCikKYGBgCgojIyBTaWduaWZpY2FudCBJc29mb3JtIFN3aXRjaGVzCgpBcnJhbmdlZCBieSBpc29mb3JtX3N3aXRjaF9xX3ZhbHVlCgpQVEMgPSBwcmUtbWF0dXJlIHRlcm1pbmF0aW9uIGNvZG9uCgpgYGB7cn0KIyBQVEMgbWVhbnMgLS0+IHByZS1tYXR1cmUgdGVybWluYXRpb24gY29kb25zCgpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9kZiA8LSBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRpc29mb3JtRmVhdHVyZXMgJT4lIAogIGFzLmRhdGEuZnJhbWUoKSAlPiUgCiAgYXJyYW5nZShpc29mb3JtX3N3aXRjaF9xX3ZhbHVlKQoKc3dpdGNoX2FuYWx5emVyX2xpc3RfZGYKI3dyaXRlLmNzdihzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9kZiwgImthbGxpc3RvX2lzb2Zvcm1fc3dpdGNoX2FuYWx5c2lzLmNzdiIsIHJvdy5uYW1lcyA9IEZBTFNFKQpgYGAKCiMjIEFkZCBEaWZmZXJlbnRpYWwgR2VuZSBhbmQgSXNvZm9ybSBFeHByZXNzaW9uCgpBZGQgcGFkaiB2YWx1ZXMKCmBgYHtyfQojIGFkZCBkaWZmZXJlbnRpYWwgZ2VuZSBhbmQgaXNvZm9ybSBleHByZXNzaW9uIHRvIHN3aXRjaGFuYWx5emVyIG9iamVjdAoKZGlmZl9nZW5lX2V4cHIgPC0gcmVhZC5jc3YoIi4uL2RpZmZlcmVudGlhbF9leHByZXNzaW9uL2thbGxpc3RvX0RHRS5jc3YiKQpkaWZmX2lzb19leHByIDwtIHJlYWQuY3N2KCIuLi9kaWZmZXJlbnRpYWxfZXhwcmVzc2lvbi9rYWxsaXN0b19kaWZmZXJlbnRpYWxfaXNvZm9ybV9leHByZXNzaW9uLmNzdiIpCgpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9kZiA8LSBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9kZiAlPiUKICBsZWZ0X2pvaW4oCiAgICBkaWZmX2dlbmVfZXhwciAlPiUgZHBseXI6OnNlbGVjdChnZW5lX25hbWUsIHBhZGopLCAKICAgIGJ5ID0gam9pbl9ieShnZW5lX2lkID09IGdlbmVfbmFtZSkpICU+JQogIG11dGF0ZShnZW5lX3FfdmFsdWUgPSBwYWRqKSAlPiUKICBzdWJzZXQoc2VsZWN0ID0gLXBhZGopICU+JQogIGxlZnRfam9pbigKICAgIGRpZmZfaXNvX2V4cHIgJT4lIGRwbHlyOjpzZWxlY3QoaXNvZm9ybV9pZCwgcGFkaiksIAogICAgYnkgPSAiaXNvZm9ybV9pZCIpICU+JQogIG11dGF0ZShpc29fcV92YWx1ZSA9IHBhZGopICU+JQogIHN1YnNldChzZWxlY3QgPSAtcGFkaikKCnN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkJGlzb2Zvcm1GZWF0dXJlcyRnZW5lX3FfdmFsdWUgPC0gc3dpdGNoX2FuYWx5emVyX2xpc3RfZGYkZ2VuZV9xX3ZhbHVlCnN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkJGlzb2Zvcm1GZWF0dXJlcyRpc29fcV92YWx1ZSA8LSBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9kZiRpc29fcV92YWx1ZQoKIyBzYXZlIHN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkIGFzIC5SRFMgZmlsZSBmb3IgZnV0dXJlIHVzZQojc2F2ZVJEUyhzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCwgZmlsZSA9ICJzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZF9zZXgucmRzIikKYGBgCgpgYGB7cn0KIyBzaWduaWZpY2FudCBpc29mb3JtIHN3aXRjaGVzIChpc29fc3dpdGNoX3FfdmFsdWUgPCAwLjA1KQpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCA8LSByZWFkUkRTKCIuL3N3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkX3NleC5yZHMiKQpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9kZiA8LSBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRpc29mb3JtRmVhdHVyZXMgJT4lIGFzLmRhdGEuZnJhbWUoKQoKc2lnbmlmaWNhbnRfaXNvX3N3aXRjaGVzIDwtIHN3aXRjaF9hbmFseXplcl9saXN0X2RmICU+JQogIGRwbHlyOjpmaWx0ZXIoaXNvZm9ybV9zd2l0Y2hfcV92YWx1ZSA8IDAuMDUpICU+JQogIGFycmFuZ2UoaXNvZm9ybV9zd2l0Y2hfcV92YWx1ZSkgJT4lCiAgZHBseXI6OnNlbGVjdChpc29mb3JtX2lkLCBnZW5lX2lkLCBjb25kaXRpb25fMSwgY29uZGl0aW9uXzIsaXNvX2Jpb3R5cGUsIElGMSwgSUYyLCBkSUYsIGlzb2Zvcm1fc3dpdGNoX3FfdmFsdWUsIGdlbmVfc3dpdGNoX3FfdmFsdWUsIFBUQykKYGBgCgojIFZvbGNhbm8tbGlrZSBQbG90IG9mIFNpZ25pZmljYW50IElzb2Zvcm0gU3dpdGNoZXMKCnJlZmVyZW5jZSBpcyBBRAoKaXNvZm9ybV9zd2l0Y2hfcV92YWx1ZSBcPCAwLjA1CgpkSUYgXDwgLTAuMSBvciBcPiAwLjEKCmBgYHtyfQojIHZvbGNhbm8tbGlrZSBwbG90IG9mIGlzb2Zvcm0gc3dpdGNoZXMgQUQgdnMgQ1RSTApnZ3Bsb3QoZGF0YSA9IHN3aXRjaF9hbmFseXplcl9saXN0X2RmLCBhZXMoeCA9IGRJRiwgeSA9IC1sb2cxMChpc29mb3JtX3N3aXRjaF9xX3ZhbHVlKSkpICsKICBnZW9tX3BvaW50KAogICAgYWVzKGNvbG9yID0gYWJzKGRJRikgPiAwLjEgJiBpc29mb3JtX3N3aXRjaF9xX3ZhbHVlIDwgMC4wNSksCiAgICBzaXplID0gMQogICkgKwogIGdlb21faGxpbmUoeWludGVyY2VwdCA9IC1sb2cxMCgwLjA1KSwgbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IGMoLTAuMSwgMC4xKSwgbGluZXR5cGUgPSAnZGFzaGVkJykgKwogIHNjYWxlX2NvbG9yX21hbnVhbCgnU2lnbmlmaWNhbnRcbklzb2Zvcm0gU3dpdGNoJywKICAgICAgICAgICAgICAgICAgICAgdmFsdWVzID0gYygnRkFMU0UnID0gJ2JsdWUnLCAnVFJVRScgPSAnb3JhbmdlJykpICsKICBsYWJzKHggPSAnZElGJywgeSA9ICctTG9nMTAgKElzb2Zvcm0gU3dpdGNoIFEgVmFsdWUpJykgKwogIGdndGl0bGUoIlNpZ25pZmljYW50IElzb2Zvcm0gU3dpdGNoZXMgQUQgdnMuIENUUkwgKFEgdmFsdWUgPCAwLjA1KSIpICsKICBnZ3JlcGVsOjpnZW9tX3RleHRfcmVwZWwoCiAgICBhZXMobGFiZWwgPSBpZmVsc2UoYWJzKGRJRikgPiAwLjEgJiBpc29mb3JtX3N3aXRjaF9xX3ZhbHVlIDwgMC4wNSwKICAgICAgICAgICAgICAgICAgICAgICBwYXN0ZTAoZ2VuZV9pZCwgIiAoIiwgaXNvZm9ybV9pZCwgIikiKSwKICAgICAgICAgICAgICAgICAgICAgICAnJykpLAogICAgc2l6ZSA9IDIuNQogICkgKwogIHRoZW1lX2J3KCkKYGBgCgojIEV4dGVybmFsIEFuYWx5c2VzCgpzaWduYWwgcGVwdGlkZXMsIHByb3RlaW4gdG9wb2xvZ3ksIHN1YmNlbGx1bGFyIGxvY2F0aW9ucywgYW5kIHByb3RlaW4gZG9tYWlucwoKYGBge3J9CiMgU2lnbmFsUCAtIFByZWRpY3Rpb24gb2YgU2lnbmFsIFBlcHRpZGVzCiMgaHR0cHM6Ly9zZXJ2aWNlcy5oZWFsdGh0ZWNoLmR0dS5kay9zZXJ2aWNlcy9TaWduYWxQLTYuMC8Kc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQgPC0gYW5hbHl6ZVNpZ25hbFAoCiAgICBzd2l0Y2hBbmFseXplUmxpc3QgICAgICAgPSBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCwKICAgIHBhdGhUb1NpZ25hbFByZXN1bHRGaWxlICA9ICIuL2Jpb2xpYl9yZXN1bHRzL3NpZ25hbHAvcHJlZGljdGlvbl9yZXN1bHRzLnR4dCIKKQoKIyBhbmFseXplRGVlcFRNSE1NIDogUHJlZGljdGlvbiBvZiBwcm90ZWluIHRvcG9sb2d5IOKAlCB0aGUgcHJvdGVpbnMgbG9jYXRpb24gY29tcGFyZWQgdG8gdGhlIGNlbGwgbWVtYnJhbmUuIENhbiBiZSBpbnRyYWNlbGx1bGFyLCB0cmFuc21lbWJyYW5lIChUTSkgb3IgZXh0cmFjZWxsdWxhci4KIyBodHRwczovL2R0dS5iaW9saWIuY29tL3Jlc3VsdHMvMDc5NzMyM2YtYzgxOC00MzQzLTg4ZDctNDMwMDkwNjJmYzU5Lz90b2tlbj1rYTJPTEFEOVhoV1BSRklPCnN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkIDwtIGFuYWx5emVEZWVwVE1ITU0oCiAgICBzd2l0Y2hBbmFseXplUmxpc3QgICA9IHN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkLAogICAgcGF0aFRvRGVlcFRNSE1NcmVzdWx0RmlsZSA9ICIuL2Jpb2xpYl9yZXN1bHRzL2RlZXB0bWhtbS9UTVJzLmdmZjMiLAogICAgc2hvd1Byb2dyZXNzPVRSVUUKKQoKIyBhbmFseXplRGVlcExvYzIgLSBwcmVkaWN0aW9uIG9mIHN1Yi1jZWxsdWxhciBsb2NhbGl6YXRpb24ocykgb2YgcHJvdGVpbgojIGRlZXBsb2MyLjAKIyBodHRwczovL3NlcnZpY2VzLmhlYWx0aHRlY2guZHR1LmRrL3NlcnZpY2VzL0RlZXBMb2MtMi4wLwpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCA8LSBhbmFseXplRGVlcExvYzIoCiAgICBzd2l0Y2hBbmFseXplUmxpc3QgPSBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCwKICAgIHBhdGhUb0RlZXBMb2MycmVzdWx0RmlsZSA9ICIuL2Jpb2xpYl9yZXN1bHRzL2RlZXBsb2MyL3Jlc3VsdHNfNjg5NEY3QTYwMDAwQkNFQTYyNkU4OTMxLmNzdiIsCiAgICBxdWlldCA9IEZBTFNFCikKCiMgcGZhbQojIHNlZSAvYmluL2lzb2Zvcm1fc3dpdGNoX2FuYWx5emVyL2Jpb2xpYl9yZXN1bHRzL3BmYW1faG1tc2Nhbi8gZGlyZWN0b3J5IGZvciBzaGVsbCBzY3JpcHQKc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQgPC0gYW5hbHl6ZVBGQU0oCiAgICBzd2l0Y2hBbmFseXplUmxpc3QgICA9IHN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkLAogICAgcGF0aFRvUEZBTXJlc3VsdEZpbGUgPSAiLi9iaW9saWJfcmVzdWx0cy9wZmFtX2htbXNjYW4vUGZhbV9yZXN1bHQudHh0IiwKICAgIHNob3dQcm9ncmVzcz1UUlVFCikKYGBgCgojIyBTaWduYWwgUGVwdGlkZSBBbmFseXNpcwoKYGBge3J9CnN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkJHNpZ25hbFBlcHRpZGVBbmFseXNpcyAlPiUgZHBseXI6OmxlZnRfam9pbihzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRpc29mb3JtRmVhdHVyZXMgJT4lIGRwbHlyOjpzZWxlY3QoaXNvZm9ybV9pZCwgZ2VuZV9uYW1lKSwgYnkgPSBqb2luX2J5KGlzb2Zvcm1faWQpKSAlPiUgZHBseXI6OnNlbGVjdChpc29mb3JtX2lkLCBnZW5lX25hbWUsIGV2ZXJ5dGhpbmcoKSkKYGBgCgojIyBUb3BvbG9neSBBbmFseXNpcwoKYGBge3J9CnN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkJHRvcG9sb2d5QW5hbHlzaXMgJT4lIGRwbHlyOjpsZWZ0X2pvaW4oc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQkaXNvZm9ybUZlYXR1cmVzICU+JSBkcGx5cjo6c2VsZWN0KGlzb2Zvcm1faWQsIGdlbmVfbmFtZSksIGJ5ID0gam9pbl9ieShpc29mb3JtX2lkKSkgJT4lIGRwbHlyOjpzZWxlY3QoaXNvZm9ybV9pZCwgZ2VuZV9uYW1lLCBldmVyeXRoaW5nKCkpCmBgYAoKIyMgU3ViY2VsbHVsYXIgTG9jYXRpb24gQW5hbHlzaXMKCmBgYHtyfQpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRzdWJDZWxsTG9jYXRpb25BbmFseXNpcyAlPiUgZHBseXI6OmxlZnRfam9pbihzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRpc29mb3JtRmVhdHVyZXMgJT4lIGRwbHlyOjpzZWxlY3QoaXNvZm9ybV9pZCwgZ2VuZV9uYW1lKSwgYnkgPSBqb2luX2J5KGlzb2Zvcm1faWQpKSAlPiUgZHBseXI6OnNlbGVjdChpc29mb3JtX2lkLCBnZW5lX25hbWUsIGV2ZXJ5dGhpbmcoKSkKYGBgCgojIyBQcm90ZWluIERvbWFpbiBBbmFseXNpcwoKU29ydGVkIGJ5IEVfdmFsdWUgKHNpZ25pZmljYW5jZSkKCmBgYHtyfQpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRkb21haW5BbmFseXNpcyAlPiUgZHBseXI6OmxlZnRfam9pbihzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRpc29mb3JtRmVhdHVyZXMgJT4lIGRwbHlyOjpzZWxlY3QoaXNvZm9ybV9pZCwgZ2VuZV9uYW1lKSwgYnkgPSBqb2luX2J5KGlzb2Zvcm1faWQpKSAlPiUgZHBseXI6OnNlbGVjdChpc29mb3JtX2lkLCBnZW5lX25hbWUsIGV2ZXJ5dGhpbmcoKSkgJT4lIGFycmFuZ2UoRV92YWx1ZSkKYGBgCgojIElzb2Zvcm0gU3dpdGNoIFBsb3RzIHdpdGggRXh0ZXJuYWwgQW5hbHlzZXMKCmBgYHtyfQojIGlzb2Zvcm0gc3dpdGNoIHZpc3VhbGl6YXRpb24KCnRvcF9zd2l0Y2hlcyA8LSBleHRyYWN0VG9wU3dpdGNoZXMoIAogICAgc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQsIAogICAgZmlsdGVyRm9yQ29uc2VxdWVuY2VzID0gRkFMU0UsIAogICAgbiA9IE5BLCAgICAgICAgICAgICAgICAgICMgbj1OQTogYWxsIGZlYXR1cmVzIGFyZSByZXR1cm5lZAogICAgZXh0cmFjdEdlbmVzID0gRkFMU0UsICAgICMgd2hlbiBGQUxTRSBpc29mb3JtcyBhcmUgcmV0dXJuZWQKICAgIHNvcnRCeVF2YWxzID0gVFJVRSwKKQoKcGxvdF9pc29mb3JtX3N3aXRjaCA8LSBmdW5jdGlvbihpc29mb3JtX3N3aXRjaF9saXN0LCBnZW5lKSB7IHN3aXRjaFBsb3QoIGlzb2Zvcm1fc3dpdGNoX2xpc3QsIGdlbmU9Z2VuZSwgY29uZGl0aW9uMSA9ICdBRCcsIGNvbmRpdGlvbjIgPSAnQ1RSTCcsIHBsb3RUb3BvbG9neSA9IFRSVUUgKSB9Cgpmb3IgKGdlbmUgaW4gdG9wX3N3aXRjaGVzJGdlbmVfaWQpIHsgcGxvdF9pc29mb3JtX3N3aXRjaChzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCwgZ2VuZSkgfQpgYGAKCiMgQWx0ZXJuYXRpdmUgU3BsaWNpbmcgQW5hbHlzaXMKClJlZmVyZW5jZSBpcyBBRAoKYGBge3J9CiMgYWx0ZXJuYXRpdmUgc3BsaWNpbmcgYW5hbHlzaXMKc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQgPC0gYW5hbHl6ZUFsdGVybmF0aXZlU3BsaWNpbmcoCiAgICBzd2l0Y2hBbmFseXplUmxpc3QgPSBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCwKICAgIHF1aWV0PVRSVUUKKQpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCRBbHRlcm5hdGl2ZVNwbGljaW5nQW5hbHlzaXMKYGBgCgpgYGB7cn0KZXh0cmFjdFNwbGljaW5nU3VtbWFyeSggc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQgKQpleHRyYWN0U3BsaWNpbmdFbnJpY2htZW50KCBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCApCmV4dHJhY3RTcGxpY2luZ0dlbm9tZVdpZGUoIHN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkICkKYGBgCgojIElzb2Zvcm0gU3dpdGNoIENvbnNlcXVlbmNlIEFuYWx5c2lzCgpgYGB7cn0KIyBzd2l0Y2ggY29uc2VxdWVuY2VzCgpjb25zZXF1ZW5jZXNPZkludGVyZXN0IDwtIGMoCiAgICAgICAgJ2ludHJvbl9yZXRlbnRpb24nLAogICAgICAgICdpbnRyb25fc3RydWN0dXJlJywKICAgICAgICAnT1JGX2dlbm9taWMnLAogICAgICAgICdPUkZfbGVuZ3RoJywKICAgICAgICAnTk1EX3N0YXR1cycsCiAgICAgICAgJ3NpZ25hbF9wZXB0aWRlX2lkZW50aWZpZWQnLAogICAgICAgICdsYXN0X2V4b24nLAogICAgICAgICdleG9uX251bWJlcicsCiAgICAgICAgJ3RzcycsCiAgICAgICAgJ3R0cycsCiAgICAgICAgJ2lzb2Zvcm1fc2VxX3NpbWlsYXJpdHknLAogICAgICAgICdpc29mb3JtX2xlbmd0aCcsCiAgICAgICAgInN1Yl9jZWxsX2xvY2F0aW9uIiwKICAgICAgICAic3ViX2NlbGxfc2hpZnRfdG9fY2VsbF9tZW1icmFuZSIsCiAgICAgICAgInN1Yl9jZWxsX3NoaWZ0X3RvX2N5dG9wbGFzbSIsCiAgICAgICAgInN1Yl9jZWxsX3NoaWZ0X3RvX251Y2xldXMiLAogICAgICAgICJzdWJfY2VsbF9zaGlmdF90b19FeHRyYWNlbGx1bGFyIiwKICAgICAgICAiaXNvZm9ybV90b3BvbG9neSIsCiAgICAgICAgImV4dHJhY2VsbHVsYXJfcmVnaW9uX2NvdW50IiwKICAgICAgICAiaW50cmFjZWxsdWxhcl9yZWdpb25fY291bnQiLAogICAgICAgICJleHRyYWNlbGx1bGFyX3JlZ2lvbl9sZW5ndGgiLAogICAgICAgICJpbnRyYWNlbGx1bGFyX3JlZ2lvbl9sZW5ndGgiLAogICAgICAgICc1X3V0cl9zZXFfc2ltaWxhcml0eScsCiAgICAgICAgJzVfdXRyX2xlbmd0aCcsCiAgICAgICAgJzNfdXRyX3NlcV9zaW1pbGFyaXR5JywKICAgICAgICAnM191dHJfbGVuZ3RoJywKICAgICAgICAnZG9tYWluc19pZGVudGlmaWVkJywKICAgICAgICAnZG9tYWluX2lzb3R5cGUnLAogICAgICAgICdkb21haW5fbGVuZ3RoJywKICAgICAgICAnZ2Vub21pY19kb21haW5fcG9zaXRpb24nCiAgICApCgpzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCA8LSBhbmFseXplU3dpdGNoQ29uc2VxdWVuY2VzKAogICAgc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQsCiAgICBjb25zZXF1ZW5jZXNUb0FuYWx5emUgPSBjb25zZXF1ZW5jZXNPZkludGVyZXN0LCAKICAgIGRJRmN1dG9mZiA9IDAuMSwKICAgIHNob3dQcm9ncmVzcz1UUlVFCikKYGBgCgojIyBUb3AgMTAgU3dpdGNoZXMgYnkgSXNvZm9ybSBTd2l0Y2ggUSBWYWx1ZQoKYGBge3J9CiMjIyBFeHRyYWN0IHRvcCBzd2l0Y2hpbmcgZ2VuZXMgKGJ5IHEtdmFsdWUpCnRvcF9zd2l0Y2hlc19xX3ZhbHVlIDwtIGV4dHJhY3RUb3BTd2l0Y2hlcygKICAgIHN3aXRjaF9hbmFseXplcl9saXN0X2ZpbHRlcmVkLCAKICAgIGZpbHRlckZvckNvbnNlcXVlbmNlcyA9IFRSVUUsIAogICAgc29ydEJ5UXZhbHMgPSBUUlVFCikKCnRvcF9zd2l0Y2hlc19xX3ZhbHVlCmBgYAoKIyMgVG9wIDEwIFN3aXRjaGVzIGJ5IGRJRiBWYWx1ZQoKYGBge3J9CiMjIyBFeHRyYWN0IHRvcCBzd2l0Y2hpbmcgZ2VuZXMgKGJ5IGRJRiB2YWx1ZXMpCnRvcF9zd2l0Y2hlc19kaWZfdmFsdWUgPC0gZXh0cmFjdFRvcFN3aXRjaGVzKAogICAgc3dpdGNoX2FuYWx5emVyX2xpc3RfZmlsdGVyZWQsIAogICAgZmlsdGVyRm9yQ29uc2VxdWVuY2VzID0gVFJVRSwgCiAgICBzb3J0QnlRdmFscyA9IEZBTFNFCikKdG9wX3N3aXRjaGVzX2RpZl92YWx1ZQpgYGAKCiMjIFN3aXRjaCBDb25zZXF1ZW5jZSBQbG90IEFEIHZzIENUUkwKClJlZmVyZW5jZSBpcyBBRAoKYGBge3J9CmV4dHJhY3RDb25zZXF1ZW5jZUVucmljaG1lbnQoCiAgICBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCwKICAgIGNvbnNlcXVlbmNlc1RvQW5hbHl6ZT0iYWxsIiwKICAgIGFuYWx5c2lzT3Bwb3NpdGVDb25zZXF1ZW5jZSA9IFRSVUUsCiAgICBsb2NhbFRoZW1lID0gdGhlbWVfYncoYmFzZV9zaXplID0gMTQpLAogICAgcmV0dXJuUmVzdWx0ID0gRkFMU0UgIyBpZiBUUlVFIHJldHVybnMgYSBkYXRhLmZyYW1lIHdpdGggdGhlIHN1bW1hcnkgc3RhdGlzdGljcwopCgpgYGAKCiMjIFBsb3Qgb2YgU3ViY2VsbHVsYXIgTG9jYXRpb24gU2hpZnRzCgpgYGB7cn0KZXh0cmFjdFN1YkNlbGxTaGlmdHMoCiAgICBzd2l0Y2hfYW5hbHl6ZXJfbGlzdF9maWx0ZXJlZCwKICAgIHBsb3RHZW5lcyA9IEZBTFNFLAogICAgbG9jYXRpb25NaW5HZW5lcyA9IDEsCiAgICByZXR1cm5SZXN1bHQgPSBGQUxTRSwKICAgIGxvY2FsVGhlbWUgPSB0aGVtZV9idygpCikKYGBgCg==